基础的游戏输入处理
在游戏开发中,处理玩家的输入是非常关键的一环。Dora SSR 引擎为我们提供了丰富的 API 来处理各种输入方式,包括触摸/点击、键盘、输入法 、鼠标和游戏控制器。本教程将带你了解如何以事件回调和每帧轮询两种方式来处理这些输入。事件回调和每帧轮询在输入处理上的主要区别在于触发机制和适用场景:
-
事件回调:是由系统在特定输入事件发生时自动触发的,响应及时,性能更高,适合处理瞬时、离散的输入事件,如点击、按键等,代码更模块化;
-
每帧轮询:需要在游戏的更新循环中主动检查输入设备的状态,适用于需要持续监控输入状态的情况,如角色移动、持续按键等,提供了更大的灵活性,但可能对性能有一定影响。综合而言,事件回调更适合即时响应的输入处理,每帧轮询则更适合需要持续检测和复杂输入逻辑的场景。
1. 触摸/点击输入
1.1 事件回调方式
Dora SSR 提供了一系列方法来监听节点的触摸/点击事件,触摸事件是指在触摸屏上的操作,点击事件是指通过鼠标设备的操作,通常这两者会有相似的处理方式。我们可以使用 onTapBegan
、onTapMoved
、onTapEnded
和 onTapped
方法来监听这些事件。需要通过创建一个场景节点对象进行调用。
- Lua
- Teal
- TypeScript
- YueScript
local Node <const> = require("Node")
local Size <const> = require("Size")
local button = Node()
button.size = Size(100, 100)
button.showDebug = true
button:onTapBegan(function(touch)
-- touch 是一个包含触摸信息的对象
-- 可以通过 touch.location 获取相对于 button 节点的触摸位置
print("点击开始于", touch.location)
end)
button:onTapMoved(function(touch)
print("点击移动到", touch.location)
end)
button:onTapEnded(function(touch)
print("点击结束于", touch.location)
end)
button:onTapped(function(touch)
print("完成一次点击于", touch.location)
end)
local Node <const> = require("Node")
local Size <const> = require("Size")
local type Touch = require("Touch")
local button = Node()
button.size = Size(100, 100)
button.showDebug = true
button:onTapBegan(function(touch: Touch.Type)
-- touch 是一个包含触摸信息的对象
-- 可以通过 touch.location 获取相对于 button 节点的触摸位置
print("点击开始于", touch.location)
end)
button:onTapMoved(function(touch: Touch.Type)
print("点击移动到", touch.location)
end)
button:onTapEnded(function(touch: Touch.Type)
print("点击结束于", touch.location)
end)
button:onTapped(function(touch: Touch.Type)
print("完成一次点击于", touch.location)
end)
import { Node, Size } from "Dora";
const button = Node();
button.size = Size(100, 100);
button.showDebug = true;
button.onTapBegan(touch => {
// touch 是一个包含触摸信息的对象
// 可以通过 touch.location 获取相对于 button 节点的触摸位置
print("点击开始于", touch.location);
});
button.onTapMoved(touch => {
print("点击移动到", touch.location);
});
button.onTapEnded(touch => {
print("点击结束于", touch.location);
});
button.onTapped(touch => {
print("完成一次点击于", touch.location);
});
_ENV = Dora
with Node!
.size = Size 100, 100
.showDebug = true
\onTapBegan (touch) ->
-- touch 是一个包含触摸信息的对象
-- 可以通过 touch.location 获取相对于 button 节 点的触摸位置
print "点击开始于", touch.location
\onTapMoved (touch) ->
print "点击移动到", touch.location
\onTapEnded (touch) ->
print "点击结束于", touch.location
\onTapped (touch) ->
print "完成一次点击于", touch.location
说明:
onTapBegan
:当触摸开始时触发。onTapMoved
:当触摸在屏幕上移动时触发。onTapEnded
:当触摸结束时触发。onTapped
:当一次完整的点击(点击并抬起)完成时触发。
触摸/点击事件过滤器
我们还可以通过注册 onTapFilter
方法来设置触摸/点击事件的过滤器,只有通过过滤器的事件才会触发回调。onTapFilter
回调会在 onTapBegan
之前触发。
- Lua
- Teal
- TypeScript
- YueScript
button:onTapFilter(function(touch)
-- 如果为多点触摸的情况,只处理第一个触摸点
if not touch.first then
-- 将触摸事件的 enabled 属性设置为 false
-- 使得该触摸事件不会触发后续的 onTapBegan 等回调
touch.enabled = false
end
end)
button:onTapFilter(function(touch: Touch.Type)
-- 如果为多点触摸的情况,只处理第一个触摸点
if not touch.first then
-- 将触摸事件的 enabled 属性设置为 false
-- 使得该触摸事件不会触发后续的 onTapBegan 等回调
touch.enabled = false
end
end)
button.onTapFilter(touch => {
// 如果为多点触摸的情况,只处理第一个触摸点
if (!touch.first) {
// 将触摸事件的 enabled 属性设置为 false
// 使得该触摸事件不会触发后续的 onTapBegan 等回调
touch.enabled = false;
}
});
button\onTapFilter (touch) ->
-- 如果为多点触摸的情况,只处理第一个触摸点
unless touch.first
-- 将触摸事件的 enabled 属性设置为 false
-- 使得该触摸事件不会触发后续的 onTapBegan 等回调
touch.enabled = false
多点触摸事件
Dora SSR 还支持多点触摸事件,可以通过 onGesture
方法来监听。
- Lua
- Teal
- TypeScript
- YueScript
button:onGesture(function(center, numTouches, deltaDist, angle)
-- center: 所有触摸位置的中心
-- numTouches: 触摸点的数量
-- deltaDist: 变化的运动比例(相对于屏幕尺寸)
-- angle: 沿着触摸中心旋转的角度,单位为弧度
print("center:", center, "numTouches:", numTouches, "deltaDist:", delta, "angle:", angle)
end)
button:onGesture(function(center: Vec2.Type, numTouches: integer, deltaDist: number, angle: number)
-- center: 所有触摸位置的中心
-- numTouches: 触摸点的数量
-- deltaDist: 变化的运动比例(相对于屏幕尺寸)
-- angle: 沿着触摸中心旋转的角度,单位为弧度
print("center:", center, "numTouches:", numTouches, "deltaDist:", delta, "angle:", angle)
end)
button.onGesture((center, numTouches, deltaDist, angle) => {
// center: 所有触摸位置的中心
// numTouches: 触摸点的数量
// deltaDist: 变化的运动比例(相对于屏幕尺寸)
// angle: 沿着触摸中心旋转的角度,单位为弧度
print("center:", center, "numTouches:", numTouches, "deltaDist:", delta, "angle:", angle);
});
button\onGesture (center, numTouches, deltaDist, angle) ->
-- center: 所有触摸位置的中心
-- numTouches: 触摸点的数量
-- deltaDist: 变化的运动比例(相对于屏幕尺寸)
-- angle: 沿着触摸中心旋转的角度,单位为弧度
print "center:", center, "numTouches:", numTouches, "deltaDist:", delta, "angle:", angle
swallowTouches
属性
通常触摸/点击事件会沿着场景节点树从根节点向下传递,并被每一个相关的节点处理。如果我们希望在某个节点上处理完触摸/点击事件后,不再继续往下传递给其子节点,可以设置 swallowTouches
属性为 true
。加上了 swallowTouches
属性的节点通常会被用作拦截触摸事件的遮罩层。
- Lua
- Teal
- TypeScript
- YueScript
button.swallowTouches = true
button.swallowTouches = true
button.swallowTouches = true;
button.swallowTouches = true
触摸事件的开关
如果需要在某个时刻暂停或恢复监听事件,如实现按钮按下后禁用点击事件,可以使用 node.touchEnabled
属性。
- Lua
- Teal
- TypeScript
- YueScript
button.touchEnabled = false
button.touchEnabled = false
button.touchEnabled = false;
button.touchEnabled = false
1.2 每帧轮询方式
由于触摸事件是即时的,不适合用每帧轮询的方式处理。然而,我们可以通过在上一级变量域范围内记录触摸状态来模拟这种方式。
- Lua
- Teal
- TypeScript
- YueScript
local Node <const> = require("Node")
local button = Node()
local isTouching = false
button:onTapBegan(function(touch)
isTouching = true
end)
button:onTapEnded(function(touch)
isTouching = false
end)
-- 在游戏的更新函数中
button:onUpdate(function()
if isTouching then
print("正在触摸")
end
end)
local Node <const> = require("Node")
local type Touch = require("Touch")
local button = Node()
local isTouching = false
button:onTapBegan(function(touch: Touch.Type)
isTouching = true
end)
button:onTapEnded(function(touch: Touch.Type)
isTouching = false
end)
-- 在游戏的更新函数中
button:onUpdate(function(): boolean
if isTouching then
print("正在触摸")
end
return false
end)
import { Node } from "Dora";
const button = Node();
let isTouching = false;
button.onTapBegan(() => {
isTouching = true;
});
button.onTapEnded(() => {
isTouching = false;
});
// 在游戏的更新函数中
button.onUpdate(() => {
if (isTouching) {
print("正在触摸");
}
return false;
});
_ENV = Dora
with Node!
isTouching = false
\onTapBegan (touch) ->
isTouching = true
\onTapEnded (touch) ->
isTouching = false
-- 在游戏的更新函数中
\onUpdate ->
if isTouching
print "正在触摸"
说明:
- 我们使用一个布尔变量
isTouching
来记录当前是否有触摸。 - 在
update
函数中,每帧检查isTouching
的状态。
2. 键盘输入
2.1 事件回调方式
可以使用 onKeyDown
、onKeyUp
和 onKeyPressed
方法来监听键盘事件。
- Lua
- Teal
- TypeScript
- YueScript
local Node <const> = require("Node")
local node = Node()
node:onKeyDown(function(keyName)
print("按下键:", keyName)
end)
node:onKeyUp(function(keyName)
print("释放键:", keyName)
end)
node:onKeyPressed(function(keyName)
print("持续按键:", keyName)
end)
local Node <const> = require("Node")
local type Keyboard = require("Keyboard")
local node = Node()
node:onKeyDown(function(keyName: Keyboard.KeyName)
print("按下键:", keyName)
end)
node:onKeyUp(function(keyName: Keyboard.KeyName)
print("释放键:", keyName)
end)
node:onKeyPressed(function(keyName: Keyboard.KeyName)
print("持续按键:", keyName)
end)
import { Node } from "Dora";
const node = Node();
node.onKeyDown(keyName => {
print("按下键:", keyName);
});
node.onKeyUp(keyName => {
print("释放键:", keyName);
});
node.onKeyPressed(keyName => {
print("持续按键:", keyName);
});
_ENV = Dora
with Node!
\onKeyDown (keyName) ->
print "按下键:", keyName
\onKeyUp (keyName) ->
print "释放键:", keyName
\onKeyPressed (keyName) ->
print "持续按键:", keyName
说明:
onKeyDown
:当按键被按下时触发。onKeyUp
:当按键被释放时触发。onKeyPressed
:当按键处于按下状态时每帧触发。
键盘事件的开关
如果需要在某个时刻暂停或恢复监听事件,可以使用 node.keyboardEnabled
属 性。
- Lua
- Teal
- TypeScript
- YueScript
node.keyboardEnabled = false
node.keyboardEnabled = false
node.keyboardEnabled = false;
node.keyboardEnabled = false
2.2 每帧轮询方式
使用 Keyboard
类的 isKeyDown
、isKeyUp
和 isKeyPressed
方法。
示例代码:
- Lua
- Teal
- TypeScript
- YueScript
local Keyboard <const> = require("Keyboard")
local Node <const> = require("Node")
local node = Node()
node:onUpdate(function()
if Keyboard:isKeyDown("A") then
print("本帧按下了键 A")
end
if Keyboard:isKeyUp("D") then
print("本帧释放了键 D")
end
if Keyboard:isKeyPressed("Space") then
print("空格键正在被按住")
end
end)
local Keyboard <const> = require("Keyboard")
local Node <const> = require("Node")
local node = Node()
node:onUpdate(function(): boolean
if Keyboard:isKeyDown("A") then
print("本帧按下了键 A")
end
if Keyboard:isKeyUp("D") then
print("本帧释放了键 D")
end
if Keyboard:isKeyPressed("Space") then
print("空格键正在被按住")
end
return false
end)
import { Keyboard, Node, KeyName } from "Dora";
const node = Node();
node.onUpdate(() => {
if (Keyboard.isKeyDown(KeyName.A)) {
print("本帧按下了键 A");
}
if (Keyboard.isKeyUp(KeyName.D)) {
print("本帧释放了键 D");
}
if (Keyboard.isKeyPressed(KeyName.Space)) {
print("空格键正在被按住");
}
return false;
});
_ENV = Dora
with Node!
\onUpdate ->
if Keyboard\isKeyDown "A"
print "本帧按下了键 A"
if Keyboard\isKeyUp "D"
print "本帧释放了键 D"
if Keyboard\isKeyPressed "Space"
print "空格键正在被按住"
解释:
isKeyDown
:检查在当前帧是否按下了指定按键。isKeyUp
:检查在当前帧是否释放了指定按键。isKeyPressed
:检查指定按键是否处于按下状态。A
、D
、Space
: 等参数为按键的名称。具体的按键名称可以参考键盘按键名称。
3. 输入法输入
3.1 事件回调方式
使用 onAttachIME
、onDetachIME
、onTextInput
和 onTextEditing
方法处理输入法事件。
- Lua
- Teal
- TypeScript
- YueScript
local Node <const> = require("Node")
local inputField = Node()
inputField:onAttachIME(function()
print("输入法监听已打开")
end)
inputField:onDetachIME(function()
print("输入法监听已关闭")
end)
inputField:onTextInput(function(text)
-- 在输入法确认输入后触发
print("输入了文本:", text)
end)
inputField:onTextEditing(function(text, startPos)
-- 输入法正在编辑文本时触发
print("输入法正在编辑文本:", text, "起始位置:", startPos)
end)
-- 在节点上激活输入法,并开始监听输入法事件
-- 同时只有一个节点可以激活输入法
-- 激活后其他节点的输入法,当前节点的监听会被停止
inputField:attachIME()
local Node <const> = require("Node")
local inputField = Node()
inputField:onAttachIME(function()
print("输入法监听已打开")
end)
inputField:onDetachIME(function()
print("输入法监听已关闭")
end)
inputField:onTextInput(function(text: string)
-- 在输入法确认输入后触发
print("输入了文本:", text)
end)
inputField:onTextEditing(function(text: string, startPos: integer)
-- 输入法正在编辑文本时触发
print("输入法正在编辑文本:", text, "起始位置:", startPos)
end)
-- 在节点上激活输入法,并开始监听输入法事件
-- 同时只有一个节点可以激活输入法
-- 激活后其他节点的输入法,当前节点的监听会被停止
inputField:attachIME()
import { Node } from "Dora";
const inputField = Node();
inputField.onAttachIME(() => {
print("输入法监听已打开");
});
inputField.onDetachIME(() => {
print("输入法监听已关闭");
});
inputField.onTextInput(text => {
// 在输入法确认输入后触发
print("输入了文 本:", text);
});
inputField.onTextEditing((text, startPos) => {
// 输入法正在编辑文本时触发
print("输入法正在编辑文本:", text, "起始位置:", startPos);
});
// 在节点上激活输入法,并开始监听输入法事件
// 同时只有一个节点可以激活输入法
// 激活后其他节点的输入法,当前节点的监听会被停止
inputField.attachIME();
_ENV = Dora
with Node!
\onAttachIME ->
print "输入法监听已打开"
\onDetachIME ->
print "输入法监听已关闭"
\onTextInput (text) ->
-- 在输入法确认输入后触发
print "输入了文本:", text
\onTextEditing (text, startPos) ->
-- 输入法正在编辑文本时触发
print "输入法正在编辑文本:", text, "起始位置:", startPos
-- 在节点上激活输入法,并开始监听输入法事件
-- 同时只有一个节点可以激活输入法
-- 激活后其他节点的输入法,当前节点的监听会被停止
\attachIME!
说明:
onAttachIME
:当输入法被激活时触发。onDetachIME
:当输入法被关闭时触发。onTextInput
:当有文本被确认输入时触发。onTextEditing
:当正在编辑文本时触发,通常是显示候选词的编辑阶段。
3.2 设置输入法位置提示
在一些小屏幕的设备上,输入法可能会遮挡输入框,或是我们希望输入法的位置跟随我们的输入框。这时可以通过设置 Keyboard.updateIMEPosHint
方法来设置输入法的位置提示。
- Lua
- Teal
- TypeScript
- YueScript
local Keyboard <const> = require("Keyboard")
local Label <const> = require("Label")
local Vec2 <const> = require("Vec2")
local label = Label("sarasa-mono-sc-regular", 40)
label.text = "请输入文本"
local function updateIMEPos(after)
-- 将输入框的右下角转换为窗口坐标
label:convertToWindowSpace(Vec2(label.width, 0), function(pos)
Keyboard:updateIMEPosHint(pos)
if after then after() end
end)
end
label:onTextInput(function(text)
label.text = label.text .. text
updateIMEPos()
end)
label:onTapped(function()
label.text = "输入中"
-- 更新输入法位置提示
updateIMEPos(function()
label:detachIME()
label:attachIME()
-- 为移动平台再次更新输入法位置
updateIMEPos()
end)
end)
local Keyboard <const> = require("Keyboard")
local Label <const> = require("Label")
local Vec2 <const> = require("Vec2")
local label = Label("sarasa-mono-sc-regular", 40)
if not label is nil then
local label = label
label.text = "请输入文本"
local function updateIMEPos(after?: function())
-- 将输入框的右下角转换为窗口坐标
label:convertToWindowSpace(Vec2(label.width, 0), function(pos: Vec2.Type)
Keyboard:updateIMEPosHint(pos)
if after then after() end
end)
end
label:onTextInput(function(text: string)
label.text = label.text .. text
updateIMEPos()
end)
label:onTapped(function()
label.text = "输入中"
-- 更新输入法位置提示
updateIMEPos(function()
label:detachIME()
label:attachIME()
-- 为移动平台再次更新输入法位置
updateIMEPos()
end)
end)
end
import { Keyboard, Label, Vec2 } from "Dora";
const label = Label("sarasa-mono-sc-regular", 40);
if (!label) error("failed to create label!");
label.text = "请输入文本";
const updateIMEPos = (after?: () => void) => {
// 将输入框的右下角转换为窗口坐标
label.convertToWindowSpace(Vec2(label.width, 0), pos => {
Keyboard.updateIMEPosHint(pos);
if (after) after();
});
};
label.onTextInput(text => {
label.text = label.text + text;
updateIMEPos();
});
label.onTapped(() => {
label.text = "输入中";
// 更新输入法位置提示
updateIMEPos(() => {
label.detachIME();
label.attachIME();
// 为移动平台再次更新输入法位置
updateIMEPos();
});
});
_ENV = Dora
with Label "sarasa-mono-sc-regular", 40
.text = "请输入文本"
updateIMEPos = (after) ->
-- 将输入框的右下角转换为窗口坐标
\convertToWindowSpace Vec2(.width, 0), (pos) ->
Keyboard\updateIMEPosHint pos
after! if after
\onTextInput (text) ->
.text ..= text
updateIMEPos!
\onTapped ->
.text = "输入中"
-- 更新输入法位置提示
updateIMEPos ->
\detachIME!
\attachIME!
-- 为移动平台再次更新输入法位置
updateIMEPos!
说明:
上述代码中,我们创建了一个输入框,当输入框被点击时,输入框会被激活输入法,同时输入法的位置会跟随输入框。当输入框输入文本时,输入法的位置也会被更新。
Keyboard.updateIMEPosHint
:设置输入法位置提示,输入法会尽量避免遮挡这个位置。label.convertToWindowSpace
:将节点坐标转换为窗口坐标,会通过回调函数返回转换后的坐标,用于设置输入法位置提示。
4. 鼠标输入
4.1 事件回调方式
使用 onMouseWheel
方法来监听鼠标滚轮事件。鼠标按键事件通常与触摸事件重叠,可以使用触摸事件的方法来处理鼠标点击。
- Lua
- Teal
- TypeScript
- YueScript
local Node <const> = require("Node")
local node = Node()
node:onMouseWheel(function(delta)
print("鼠标滚轮滚动:", delta.x, delta.y)
end)
local Node <const> = require("Node")
local type Vec2 = require("Vec2")
local node = Node()
node:onMouseWheel(function(delta: Vec2.Type)
print("鼠标滚轮滚动:", delta.x, delta.y)
end)
import { Node } from "Dora";
const node = Node();
node.onMouseWheel(delta => {
print("鼠标滚轮滚动:", delta.x, delta.y);
});
_ENV = Dora
with Node!
\onMouseWheel (delta) ->
print "鼠标滚轮滚动:", delta.x, delta.y
说明:
onMouseWheel
:当鼠标滚轮滚动时触发,delta
包含滚动的距离信息,包含x
和y
两个方向的滚动值。
鼠标滚动事件的开关
鼠标滚动事件也受到 node.touchEnabled
属性的控制。当 node.touchEnabled
被设置为 false
时,鼠标滚动事件也会被禁用。
4.2 每帧轮询方式
使用 Mouse
类的属性来获取鼠标状态。
- Lua
- Teal
- TypeScript
- YueScript
local Mouse <const> = require("Mouse")
local Node <const> = require("Node")
local node = Node()
node:onUpdate(function()
-- 将鼠标屏幕坐标转换为游戏世界坐标
local bs = App.bufferSize
local bw = bs.width
local bh = bs.height
local pos = Mouse.position * (bw / App.visualSize.width)
local worldPos = Vec2(pos.x - bw / 2, bh / 2 - pos.y)
-- 将世界坐标转换为节点坐标
local nodePos = node:convertToNodeSpace(worldPos)
print("鼠标位置:", nodePos)
if Mouse.leftButtonPressed then
print("鼠标左键被按下")
end
if Mouse.rightButtonPressed then
print("鼠标右键被按下")
end
if Mouse.middleButtonPressed then
print("鼠标中键被按下")
end
if Mouse.wheel ~= Vec2.zero then
print("鼠标滚轮值:", Mouse.wheel)
end
end)
local Mouse <const> = require("Mouse")
local Node <const> = require("Node")
local node = Node()
node:onUpdate(function(): boolean
-- 将鼠标屏幕坐标转换为游戏世界坐标
local bs = App.bufferSize
local bw = bs.width
local bh = bs.height
local pos = Mouse.position * (bw / App.visualSize.width)
local worldPos = Vec2(pos.x - bw / 2, bh / 2 - pos.y)
-- 将世界坐标转换为节点坐标
local nodePos = node:convertToNodeSpace(worldPos)
print("鼠标位置:", nodePos)
if Mouse.leftButtonPressed then
print("鼠标左键被按下")
end
if Mouse.rightButtonPressed then
print("鼠标右键被按下")
end
if Mouse.middleButtonPressed then
print("鼠标中键被按下")
end
if Mouse.wheel ~= Vec2.zero then
print("鼠标滚轮值:", Mouse.wheel)
end
return false
end)
import { Mouse, Node, App, Vec2 } from "Dora";
const node = Node();
node.onUpdate(() => {
// 将鼠标屏幕坐标转换为游戏世界坐标
const bs = App.bufferSize;
const bw = bs.width;
const bh = bs.height;
const pos = Mouse.position.mul(bw / App.visualSize.width);
const worldPos = Vec2(pos.x - bw / 2, bh / 2 - pos.y);
// 将世界坐标转换为节点坐标
const nodePos = node.convertToNodeSpace(worldPos);
print("鼠标位置:", nodePos);
if (Mouse.leftButtonPressed) {
print("鼠标左键被按下");
}
if (Mouse.rightButtonPressed) {
print("鼠标右键被按下");
}
if (Mouse.middleButtonPressed) {
print("鼠标中键被按下");
}
if (!Mouse.wheel.equals(Vec2.zero)) {
print("鼠标滚轮值:", Mouse.wheel);
}
return false;
});
_ENV = Dora
with Node!
\onUpdate ->
-- 将鼠标屏幕坐标转换为游戏世界坐标
width: bw, height: bh = App.bufferSize
pos = Mouse.position * (bw / App.visualSize.width)
worldPos = Vec2 pos.x - bw / 2, bh / 2 - pos.y
-- 将世界坐标转换为节点坐标
nodePos = \convertToNodeSpace worldPos
print "鼠标位置:", nodePos
if Mouse.leftButtonPressed
print "鼠标左键被按下"
if Mouse.rightButtonPressed
print "鼠标右键被按下"
if Mouse.middleButtonPressed
print "鼠标中键被按下"
if Mouse.wheel != Vec2.zero
print "鼠标滚轮值:", Mouse.wheel
说明:
Mouse.position
:获取鼠标在窗口中的位置。leftButtonPressed
等属性:判断鼠标按键的按下状态。Mouse.wheel
:获取鼠标滚轮的滚动值。
5. 游戏控制器输入
5.1 事件回调方式
使用 onButtonDown
、onButtonUp
、onButtonPressed
和 onAxis
方法来监听控制器事件。
- Lua
- Teal
- TypeScript
- YueScript
local Node <const> = require("Node")
local node = Node()
node:onButtonDown(function(controllerId, buttonName)
print("控制器", controllerId, "按下按钮:", buttonName)
end)
node:onButtonUp(function(controllerId, buttonName)
print("控制器", controllerId, "释放按钮:", buttonName)
end)
node:onButtonPressed(function(controllerId, buttonName)
print("控制器", controllerId, "持续按住按钮:", buttonName)
end)
node:onAxis(function(controllerId, axisName, value)
print("控制器", controllerId, "轴", axisName, "的值:", value)
end)
local Node <const> = require("Node")
local type Controller = require("Controller")
local node = Node()
node:onButtonDown(function(controllerId: integer, buttonName: Controller.ButtonName)
print("控制器", controllerId, "按下按钮:", buttonName)
end)
node:onButtonUp(function(controllerId: integer, buttonName: Controller.ButtonName)
print("控制器", controllerId, "释放按钮:", buttonName)
end)
node:onButtonPressed(function(controllerId: integer, buttonName: Controller.ButtonName)
print("控制器", controllerId, "持续按住按钮:", buttonName)
end)
node:onAxis(function(controllerId: integer, axisName: Controller.AxisName, value: number)
print("控制器", controllerId, "轴", axisName, "的值:", value)
end)
import { Node } from "Dora";
const node = Node();
node.onButtonDown((controllerId, buttonName) => {
print("控制器", controllerId, "按下按钮:", buttonName);
});
node.onButtonUp((controllerId, buttonName) => {
print("控制器", controllerId, "释放按钮:", buttonName);
});
node.onButtonPressed((controllerId, buttonName) => {
print("控制器", controllerId, "持续按住按钮:", buttonName);
});
node.onAxis((controllerId, axisName, value) => {
print("控制器", controllerId, "轴", axisName, "的值:", value);
});
_ENV = Dora
with Node!
\onButtonDown (controllerId, buttonName) ->
print "控制器", controllerId, "按下按钮:", buttonName
\onButtonUp (controllerId, buttonName) ->
print "控制器", controllerId, "释放按钮:", buttonName
\onButtonPressed (controllerId, buttonName) ->
print "控制器", controllerId, "持续按住按钮:", buttonName
\onAxis (controllerId, axisName, value) ->
print "控制器", controllerId, "轴", axisName, "的值:", value
说明:
onButtonDown
:当控制器按钮被按下时触发。onButtonUp
:当控制器按钮被释放时触发。onButtonPressed
:当控制器按钮被按住时每帧触发。buttonName
:按钮的名称,如a
、b
、x
、y
等。具体的按钮名称可以参考控制器按钮名称。onAxis
:当控制器的轴(如摇杆、扳机)发生变化时触发。axisName
:轴的名称,如leftx
、lefty
、rightx
、righty
等。具体的轴名称可以参考控制器轴名称。
控制器事件的开关
如果需要在某个时刻暂停或恢复监听事件,可以使用 node.controllerEnabled
属性。
- Lua
- Teal
- TypeScript
- YueScript
node.controllerEnabled = false
node.controllerEnabled = false